A processor instruction can be considered to consist of two portions: an opcode portion and an operand portion. The opcode in the opcode portion defines the type of instruction and, when decoded by the processor's execution unit, causes the processor to perform the corresponding operation (add, subtract, I/O, etc.) The operand portion may contain one or more operand specifiers. These operand specifiers specify which of the processor's operand registers, if any, the instruction defined by the opcode is to operate upon. Alternatively, or additionally, the operand portion may contain an “immediate” operand, i.e. an operand which is contained directly within the operand portion of the instruction, rather than being taken from a specified register. If the instruction does not involve any operands then the operand portion may go unused, or more likely may be used to encode additional opcodes.
Given that the instructions typically have predetermined sizes or formats, this means a trade-off must be made when designing a processor between the size of the opcode and the size of the operand portion.
When small opcodes are used, then only a limited set of instructions can be encoded due to the limited permutations of opcode bits. Such instruction sets would usually comprise only simple, low-level machine code for performing fundamental operations of the processor. This results in a low code density, in the sense that fewer operations can be stored per unit of instruction data, because complex operations must be defined in software as whole sequences of lower-level instructions. In some less usual processors, small opcodes may be used to encode a small number of more complex instructions, whereby complex operations are implemented in hardware and invoked by dedicated instructions. But then the limited number of opcodes available results in the processor only having a very specialised set of possible operations. In any case, small opcodes limit the instruction set size and so limit the processor. However, there is also an advantage in using small opcodes, in that more bits may be available in the instruction for operands.
When large opcodes are used, more numerous types of instruction can be encoded due to the larger number of permutations of opcode bits. Thus, a greater variety of instruction types is available to the processor designer. However, the disadvantage is that fewer bits are available in the instruction for operands.
Thus it can be seen how opcode size must be balanced against the size of the operand portion.
For example, FIG. 1 illustrates a conventional instruction format having sixteen bits i[15:0]. The sixteen instruction bits are each input to an execution unit's decoding logic from an instruction register 50. The decoding logic comprises opcode decoding logic 70 which decodes a four-bit opcode portion 102 of the instruction, and operand decoding logic 80 which determines three four-bit operand specifiers from three respective operand portions 104, 106 and 108 of the instruction. According to this format, each of the three operand specifiers can take a value from zero (0000) to fifteen (1111) in order to specify any one of a set of sixteen operand registers from which to read a source operand or to store a destination operand.
A problem with this conventional sixteen-bit style instructions is that, with sixteen possible operand registers and three operand specifiers 104, 106 and 108, then twelve bits i[11:0] of each instruction are taken up with the operand specifiers. This leaves only four bits i[15:12] for the instruction opcode 102, which only allows sixteen different instructions to be encoded. Existing techniques to overcome this have involved providing restricted operand specifiers (such as ARM Thumb which uses only three bits) or providing most instructions with only two register operands. Other solutions involve moving away from a sixteen-bit instruction format. However, this has its own complications due to the fact that the instruction size is not a conveniently expressed in a number of bytes, or otherwise requires needlessly large twenty-four or thirty-two bit instructions.
Further, the instruction set complexity may affect the processor's speed. Large instruction set processors can sometimes be faster than small instruction set processors because less code is required to execute complex operations. However, the speed of the execution unit is limited by the time to decode the most complex instruction. Therefore larger instruction set processors may actually be slower if there are too many superfluous, unused, or needlessly complex instructions in the set.
Further, compared to large instruction sets, small instruction sets require less hardware logic in the execution unit in order to decode and execute the opcodes, although small sets typically also require more program memory and use more operand registers. The size of the instruction set may therefore have a bearing on the cost, power consumption and silicon area of the processor, depending on the operand registers, decode logic and program memory that are required in conjunction with a particular instruction format.
It is an aim of the present invention to find a preferred balance between the size of an instruction's opcode and the size of it's operand portion, and to achieve this using an encoding scheme which can condense opcodes efficiently into a given instruction length whilst also being quick to decode. It is a particular aim of the invention to find a balance which is advantageous for use in a processor for interfacing with external devices. It is another particular aim of the invention to find a balance which is advantageous for use in a processor for managing the execution of a plurality of threads.